package com.tanovo.service.impl;

import com.tanovo.bo.Token;
import com.tanovo.bo.TokenRequest;
import com.tanovo.bo.WechatToken;
import com.tanovo.domain.CompanyMapUser;
import com.tanovo.domain.OauthClientDetails;
import com.tanovo.domain.OauthClientToken;
import com.tanovo.domain.User;
import com.tanovo.exception.ServiceException;
import com.tanovo.service.*;
import com.tanovo.util.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.Date;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class TokenServiceImpl implements ITokenService {
    @Autowired
    private IOauthClientDetailsService iOauthClientDetailsService;

    @Autowired
    private IUserService iUserService;

    @Autowired
    private IOauthClientTokenService iOauthClientTokenService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private ICompanyService iCompanyService;
    @Value("${wechat.web.scan.appid}")
    private String appid;
    @Value("${wechat.web.scan.appsecret}")
    private String secret;
    @Value("${wechat.web.scan.url}")
    private String weixinBaseUrl;

    @Override
    public Token getUserToken(TokenRequest tokenRequest) {
        User user = iUserService.getUserbyTokenReqest(tokenRequest);
        if (user == null) {
            throw new ServiceException("用户名或密码错误");
        }
        Date date = new Date();
        //获取当前用户 登录公司 并且设置默认登录公司
        tokenRequest.setUserId(user.getId());
        CompanyMapUser companyMapUser = iCompanyService.getLoginDefaultCompany(user.getId());
        tokenRequest.setCompanyId(companyMapUser.getCompanyId());
        //判断用户是否被禁用
        if (companyMapUser.getEnable() == 0) {
            throw new ServiceException("用户被禁用");
        }

        // 如果token存在
        OauthClientToken dbToken = iOauthClientTokenService.getOauthClientToken(tokenRequest);
        if (dbToken != null) {
            iOauthClientTokenService.deleteToken(dbToken);
         /*   if (date.compareTo(dbToken.getExpiredTime()) > 0) {//超时的token 处理

            } else {
                Token token = new Token();
                token.setToken(dbToken.getToken());
                return token;
            }*/
        }
        //不存在 新建并入库
        Token token = new Token();
        OauthClientToken oauthClientToken = this.setOauthClientToken(tokenRequest);
        token.setToken(oauthClientToken.getToken());
        iOauthClientTokenService.saveToken(oauthClientToken);
        return token;
    }

    private OauthClientToken setOauthClientToken(TokenRequest tokenRequest) {
        OauthClientToken oauthClientToken = new OauthClientToken();
        oauthClientToken.setClientId(tokenRequest.getClientId());
        oauthClientToken.setUserId(tokenRequest.getUserId().toString());
        oauthClientToken.setToken(UUID.randomUUID().toString());
        oauthClientToken.setDelFlag(0);
        oauthClientToken.setCompanyId(tokenRequest.getCompanyId());
        Date expiredLongTime = DateUtil.addMINUTE(new Date(), 30 * 24 * 60);
        oauthClientToken.setExpiredTime(expiredLongTime);
        oauthClientToken.setDelFlag(0);
        oauthClientToken.setCreateTime(new Date());
        oauthClientToken.setUpdateTime(new Date());
        oauthClientToken.setUpdateBy(tokenRequest.getUserId().toString());
        oauthClientToken.setCreateBy(tokenRequest.getUserId().toString());
        return oauthClientToken;
    }


    @Override
    public Token getWechatToken(String code, String clientId) {
        String url = weixinBaseUrl + "?appid=" + appid + "&secret=" + secret + "&code=" + code + "&grant_type=authorization_code";
        ResponseEntity<WechatToken> responseEntity = restTemplate.getForEntity(url, WechatToken.class);
        WechatToken wechatToken = responseEntity.getBody();
        String unionid = wechatToken.getUnionid();
//        String openid = wechatToken.getOpenid();
        User user = iUserService.getUserByUnionid(unionid);
        if (null != user) {
            TokenRequest tokenRequest = new TokenRequest();
            tokenRequest.setUserId(user.getId());
            tokenRequest.setClientId(clientId);
            OauthClientDetails oauthClientDetails = iOauthClientDetailsService.getOauthClientDetails(tokenRequest);
            if (oauthClientDetails == null) {
                throw new ServiceException("oauthClientDetails不存在");
            }
            OauthClientToken clientToken = iOauthClientTokenService.getOauthClientToken(tokenRequest);
            if (clientToken != null) {
                Date date = new Date();
                if (date.compareTo(clientToken.getExpiredTime()) > 0) {//超时的token 处理
                    iOauthClientTokenService.deleteToken(clientToken);
                } else {
                    Token token = new Token();
                    token.setToken(clientToken.getToken());
                    token.setExpiredTime(oauthClientDetails.getAccessTokenValidity());
                    return token;
                }
            }
            Token token = new Token();
            OauthClientToken oauthClientToken = setOauthClientToken(tokenRequest);
            token.setToken(oauthClientToken.getToken());
            iOauthClientTokenService.saveToken(oauthClientToken);
            return token;
        }
        throw new ServiceException("用户没有绑定微信");

    }

    @Override
    public Boolean checkToken(String token) {
        OauthClientToken oauthClientToken = iOauthClientTokenService.getByToken(token);
        if (oauthClientToken == null) {
            return false;
        }
        Date date = new Date();
        if (date.compareTo(oauthClientToken.getExpiredTime()) > 0) {//超时的token 处理
            iOauthClientTokenService.deleteToken(oauthClientToken);
            return false;
        }
        return true;
    }
}
